package com.auxgroup.smarthome.inner.service;

import com.auxgroup.bridge.app.inner.dto.AppUserDto;
import com.auxgroup.bridge.app.inner.vo.AppUserPushVo;
import com.auxgroup.bridge.app.inner.vo.AppUserVo;
import com.auxgroup.bridge.business.inner.vo.DeviceUserListVo;
import com.auxgroup.smarthome.BeanListUtils;
import com.auxgroup.smarthome.BeanUtils;
import com.auxgroup.smarthome.inner.entity.AppUserEntity;
import com.auxgroup.smarthome.inner.entity.TemplateConditionBean;
import com.auxgroup.smarthome.inner.entity.UserDeviceEntity;
import com.auxgroup.smarthome.inner.repo.AppUserEntityRepo;
import com.auxgroup.smarthome.inner.repo.UserDeviceEntityRepo;
import com.auxgroup.smarthome.redis.config.ObjectRedis;
import com.auxgroup.smarthome.syscode.AppCode;
import com.auxgroup.smarthome.utils.EmojiUtil;
import com.auxgroup.smarthome.utils.NewDateUtils;
import com.auxgroup.smarthome.web.ApiResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by kevinchen on 2017/7/24.
 */
@Service
public class AppUserDBService {

    @Autowired
    private AppUserEntityRepo appUserEntityRepo;
    @Autowired
    private ObjectRedis objectRedis;
    @Autowired
    private UserDeviceEntityRepo userDeviceEntityRepo;

    /**
     * 创建手机用户
     *
     * @param uid
     * @param phone
     * @return
     */
    public ApiResponse<AppUserVo> createPhoneUser(String uid, String phone) {
        AppUserEntity user = appUserEntityRepo.save(new AppUserEntity().createAppUser(uid, phone));
        if (user == null) {
            return ApiResponse.ok(null);
        }
        AppUserVo appUserVo = BeanUtils.copyAttrs(new AppUserVo(), user);
        return ApiResponse.ok(appUserVo);
    }

    /**
     * 创建第三方帐号 20180410
     *
     * @param uid
     * @param openid
     * @param nickName
     * @param headImg
     * @return
     */
    public ApiResponse<AppUserVo> createOtherUser(String uid, String openid, String unionid, String nickName, String headImg, String src) {
        //判断nickname是否为emoji表情
        String nickNameFilter = EmojiUtil.filterEmoji(nickName);
        AppUserEntity user = null;
        if ("qq".equals(src)) {
            user = appUserEntityRepo.save(new AppUserEntity().createQqAppUser(uid, openid, nickNameFilter, headImg));
        } else if ("wechat".equals(src)) {
            user = appUserEntityRepo.save(new AppUserEntity().createWechatAppUser(uid, openid, unionid, nickNameFilter, headImg));
        }
        if (user == null) {
            return ApiResponse.ok(null);
        }
        AppUserVo appUserVo = BeanUtils.copyAttrs(new AppUserVo(), user);
        return ApiResponse.ok(appUserVo);
    }

    /**
     * 获取所有的用户
     *
     * @return
     */
    public List<AppUserVo> getAllAppUser(String keywords) {
        Specification<AppUserEntity> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotEmpty(keywords)) {
                predicates.add(cb.or(cb.like(root.get("nickName"), "%" + keywords + "%"),
                        cb.like(root.get("realName"), "%" + keywords + "%"),
                        cb.like(root.get("phone"), "%" + keywords + "%")));
            }
            Predicate[] options = new Predicate[predicates.size()];
            return query.where(predicates.toArray(options)).getRestriction();
        };
        Sort sort = new Sort(Sort.Direction.DESC, "createdAt");
        List<AppUserEntity> users = appUserEntityRepo.findAll(specification, sort);
        List<AppUserVo> appUserVos = new ArrayList<AppUserVo>();
        users.stream().forEach(appUserEntity -> {
            AppUserVo appUserVo = new AppUserVo();
            org.springframework.beans.BeanUtils.copyProperties(appUserEntity, appUserVo);
            appUserVos.add(appUserVo);
        });
        return appUserVos;
    }

    /**
     * 获取app用户列表
     *
     * @param keywords
     * @param pageable
     * @return
     */
    public Page<AppUserVo> getAppUserList(String keywords, Pageable pageable) {
        Specification<AppUserEntity> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotEmpty(keywords)) {
                predicates.add(cb.or(cb.like(root.get("nickName"), "%" + keywords + "%"),
                        cb.like(root.get("realName"), "%" + keywords + "%"),
                        cb.like(root.get("phone"), "%" + keywords + "%")));
            }
            Predicate[] options = new Predicate[predicates.size()];
            return query.where(predicates.toArray(options)).getRestriction();
        };
        Sort sort = new Sort(Sort.Direction.DESC, "createdAt");
        pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), sort);
        Page<AppUserEntity> all = appUserEntityRepo.findAll(specification, pageable);
        List<AppUserEntity> contents = all.getContent();
        List<AppUserVo> appUserVos = new ArrayList<AppUserVo>();
        contents.stream().forEach(appUserEntity -> {
            AppUserVo appUserVo = BeanUtils.copyAttrs(new AppUserVo(), appUserEntity);
            appUserVos.add(appUserVo);
        });
        return new PageImpl(appUserVos, pageable, all.getTotalElements());
    }

    /**
     * 编辑用户
     *
     * @param appUserDto
     * @return
     */
    public ApiResponse<AppUserVo> updateAppUser(String uid, AppUserDto appUserDto) {
        //验证生日格式
        String birthday = appUserDto.getBirthday();
        if (StringUtils.isNotEmpty(birthday) && !isValidDate(birthday)) {
            return ApiResponse.prompt(AppCode.TIME_FORMAT_ERROR);
        }
        AppUserEntity appUserEntity = appUserEntityRepo.findByUid(uid);
        if (appUserEntity == null) {
            return ApiResponse.prompt(AppCode.ACCOUNT_IS_NOT_EXISTS);
        }
        appUserEntity.updateUser(appUserDto);
        appUserEntity = appUserEntityRepo.save(appUserEntity);
        if (appUserEntity == null) {
            return ApiResponse.prompt(AppCode.SYSTEM_EXCEPTION);
        }
        List<UserDeviceEntity> userDeviceEntities = userDeviceEntityRepo.findByUidAndTrashFalse(appUserEntity.getUid());
        final String username = appUserEntity.getRealName();
        userDeviceEntities.stream().forEach(x -> x.setUsername(username));
        userDeviceEntityRepo.save(userDeviceEntities);
        AppUserVo appUserVo = BeanUtils.copyAttrs(new AppUserVo(), appUserEntity);
        objectRedis.add(appUserVo.getUid(), 6 * 24 * 60L, appUserVo);
        return ApiResponse.ok(appUserVo);
    }

    private boolean isValidDate(String str) {
        //String str = "2007-01-02";
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = formatter.parse(str);
            return str.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 记录登录信息
     *
     * @param uid
     * @param clientId 登录设备唯一标识
     * @param ip       登录设备的ip地址
     * @return
     */
    public boolean recordLoginInfo(String uid, String clientId, String ip) {
        AppUserEntity appUserEntity = appUserEntityRepo.findByUid(uid);
        if (appUserEntity == null)
            return false;
        appUserEntity.recordLoginInfo(clientId, ip);
        int currentTimstamp = Long.valueOf(NewDateUtils.getCurrentEpochSecond()).intValue();
        appUserEntity.setLastLoginTime(currentTimstamp);

        // 真实姓名为空默认为手机号码
        if (StringUtils.isBlank(appUserEntity.getRealName())) {
            appUserEntity.setRealName(appUserEntity.getPhone());
        }

        appUserEntityRepo.save(appUserEntity);
        return true;
    }

    /**
     * 获取app用户信息
     * 支持缓存
     *
     * @param uid
     * @return
     */
    public AppUserVo findAppUser(String uid) {
        AppUserEntity appUserEntity = appUserEntityRepo.findByUid(uid);
        if (appUserEntity == null) {
            return null;
        }
        AppUserVo appUserVo = BeanUtils.copyAttrs(new AppUserVo(), appUserEntity);
        return appUserVo;
    }


    /**
     * 根据条件查找用户信息
     *
     * @param gender 性别
     * @param map    key/value 所在城市/所在省份
     * @return
     */
    public ApiResponse<List<AppUserPushVo>> filterUsers(String gender, Map<String, String> map) {
        List<AppUserEntity> appUserEntityList = getAppUserEntities(gender, map);
        return ApiResponse.ok(new BeanListUtils(AppUserPushVo.class, appUserEntityList).getTargetList());
    }

    public List<AppUserEntity> getAppUserEntities(String gender, Map<String, String> map) {
        List<AppUserEntity> appUserEntityList = new ArrayList<>();
        if (map == null || map.size() == 0) {
            //add by lixiaoxiao 20171031 当用户性别选择N时,推送全部
            if ("M".equals(gender) || "F".equals(gender)) {
                appUserEntityList = appUserEntityRepo.findByGender(gender);
            } else {
                appUserEntityList = appUserEntityRepo.findByOpenidIsNullAndQqidIsNull();
            }
        }
        if (map != null && map.size() > 0 && map.size() < 5) {
            for (Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
                 iterator.hasNext(); ) {
                Map.Entry<String, String> next = iterator.next();
                //String region = next.getKey();
                String city = next.getValue();
                List<AppUserEntity> appUserEntities = new ArrayList<>();
                //add by lixiaoxiao 20171031 当用户性别选择N时,推送全部
                if ("M".equals(gender) || "F".equals(gender)) {
                    appUserEntities = appUserEntityRepo.findByGenderAndAndCity(gender, city);
                } else {
                    appUserEntities = appUserEntityRepo.findByCity(city);
                }
                appUserEntityList.addAll(appUserEntities);
            }
        }
        return appUserEntityList;
    }


    /**
     * 根据条件查找用户信息
     *
     * @return
     */
    public ApiResponse<List<AppUserPushVo>> filterUsers(TemplateConditionBean conditionBean) {
        List<AppUserEntity> appUserEntityList = new ArrayList<>();
        String objectType = conditionBean.getObjectType();
        if (objectType.equals("all")) {
            appUserEntityList = appUserEntityRepo.findByOpenidIsNullAndQqidIsNull();
        } else if (objectType.equals("single")) {
            String phone = conditionBean.getPhone();
            AppUserEntity appUserEntity = appUserEntityRepo.findByPhoneAndOpenidIsNullAndQqidIsNull(phone);
            appUserEntityList.add(appUserEntity);
        }else {
            String gender=conditionBean.getGender();
            Map<String,String> map=conditionBean.getCitys();
            appUserEntityList = getAppUserEntities(gender, map);
        }
        return ApiResponse.ok(new BeanListUtils(AppUserPushVo.class, appUserEntityList).getTargetList());

    }


    /**
     * 通过mac地址获取设备的绑定用户列表（分页）
     *
     * @param mac
     * @param pageable
     * @return
     */
    public ApiResponse<Page<DeviceUserListVo>> findDeviceUserPage(String mac, Pageable pageable) {
        StringBuilder sb = new StringBuilder();
        sb.append(" SELECT DISTINCT aui.*, ud.user_tag FROM device_info d");
        sb.append(" LEFT OUTER JOIN user_device ud ON d.device_id = ud.device_id AND ud.is_trash = 0");
        sb.append(" LEFT OUTER JOIN app_user_info aui ON ud.uid = aui.uid");
        sb.append(" WHERE d.mac = ?");
        Page<DeviceUserListVo> resultList = appUserEntityRepo.findBySql(sb.toString(), Arrays.asList(mac), pageable, DeviceUserListVo.class);
        return ApiResponse.ok(resultList);
    }

    /**
     * 绑定第三方帐号 20180410
     *
     * @param uid
     * @param openid
     * @param qqid
     * @param phone
     * @return
     */
    public ApiResponse bindOtherAccount(String uid, String openid, String qqid, String phone) {
        appUserEntityRepo.bindOtherAccount(openid, qqid, phone, uid);
        return ApiResponse.ok();
    }

    /**
     * 查找第三方关联帐号 20180410
     *
     * @param openid
     * @return
     */
    public ApiResponse<List<AppUserVo>> findByOpenid(String openid, String qqid) {
        List<AppUserEntity> appUserEntityList = null;
        if (StringUtils.isNotEmpty(openid)) {
            appUserEntityList = appUserEntityRepo.findByOpenid(openid);
        } else if (StringUtils.isNotEmpty(qqid)) {
            appUserEntityList = appUserEntityRepo.findByQqid(qqid);
        }

        return ApiResponse.ok(new BeanListUtils(AppUserVo.class, appUserEntityList).getTargetList());
    }

    /**
     * 通过手机号获取app用户信息 180507 add by lixiaoxiao
     *
     * @param phone
     * @return
     */
    public AppUserVo findAppUserByPhone(String phone) {
        AppUserEntity appUserEntity = appUserEntityRepo.findByPhoneAndOpenidIsNullAndQqidIsNull(phone);
        if (null == appUserEntity) {
            return null;
        }
        AppUserVo appUserVo = BeanUtils.copyAttrs(new AppUserVo(), appUserEntity);
        return appUserVo;
    }
}
